package javagame;

import com.sun.org.apache.xerces.internal.impl.xpath.regex.Match;
import java.awt.*;

public class Entity implements Comparable<Entity> {
    protected Game game;
    protected int x, y, direction, speed, hspeed, vspeed, depth;
    protected Picture picture;
    protected int picture_total_frames, picture_current_frame, picture_speed, picture_change_counter;
    protected boolean visible, solid;
    protected Rectangle box;
    
    public Entity() {
        game = null;
        x = 0;
        y = 0;
        depth = 0;
        hspeed = 0;
        vspeed = 0;
        picture_speed = -1;
        speed = 0;
        direction = 0;
        picture = null;
        visible = true;
        solid = false;
        box = null;
    }
    
    public void setPicture(Picture s) {
        picture = s;
        picture_change_counter = 0;
        picture_current_frame = 0;
        picture_total_frames = s.getFrameCount();
        box = new Rectangle(x, y, picture.getWidth(), picture.getHeight());
    }
    
    public void setDepth(int dep) {
        depth = dep;
        game.resort();
    }
    
    public int getDepth() {
        return depth;
    }
    
    public void setDirection(int d) {
        direction = d;
        vspeed = speed * (int) Math.sin(direction);
        hspeed = speed * (int) Math.cos(direction);
    }
    
    public int getDirection() {
        return direction;
    }
    
    public int getDirectionTo(Entity e) {
        return (int) Math.atan( (e.getY() - y) / (e.getX() - x) );
    }
    
    public void setHSpeed(int hs) {
        hspeed = hs;
        if(hspeed != 0) {
            direction = (int) Math.atan(vspeed / hspeed);
        }
        speed = (int) Math.sqrt(hspeed * hspeed + vspeed * vspeed);
    }
    
    public int getHSpeed() {
        return hspeed;
    }
    
    public void setVSpeed(int vs) {
        vspeed = vs;
        if(hspeed != 0) {
            direction = (int) Math.atan(vspeed / hspeed);
        }
        speed = (int) Math.sqrt(hspeed * hspeed + vspeed * vspeed);
    }
    
    public int getVSpeed() {
        return vspeed;
    }
    
    public void setSpeed(int s) {
        speed = s;
        vspeed = (int) (speed * Math.sin(direction));
        hspeed = (int) (speed * Math.cos(direction));
    }
    
    public int getSpeed() {
        return speed;
    }
    
    public void setPictureSingle(int frame) {
        if(frame < picture_total_frames && frame >= 0) {
            picture_current_frame = frame;
        }
        picture_speed = -1;
    }
    
    public void setPictureSpeed(int ss) {
        picture_speed = ss;
    }
    
    // Called by Game class to initialize this entity. DO NOT USE THIS.
    public void register(Game _game) {
        game = _game;
    }
    
    // Called by Game class to deinitialize this entity. DO NOT CALL THIS.
    public void deregister() {
        game = null;
    }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;
    }
    
    public void move(int newx, int newy) {
        if(box != null) {
            box.x += newx - x;
            box.y += newy - y;
        }
        x = newx;
        y = newy;
    }
    
    public void tick(long delta) {
        // Move the entity.
        move(x + hspeed, y + vspeed);
        
        // Change the frame of the picture, if it's animated.
        if(picture_speed >= 0) {
            picture_change_counter++;
            if(picture_change_counter >= picture_speed) {
                picture_current_frame = ++picture_current_frame % picture_total_frames;
                picture_change_counter = 0;
            }
        }
        
        // Perform user-defined events.
        step();
    }
    
    public void create() {
        //
    }
    
    // Called once every frame.
    public void step() {
        //
    }
    
    // Called when this entity collides with another entity.
    public void collide(Entity other) {
        //
    }
    
    public void show() {
        visible = true;
    }
    
    public void hide() {
        visible = false;
    }
    
    public boolean isVisible() {
        return visible;
    }
    
    public void setSolid(boolean mys) {
        solid = mys;
    }
    
    public boolean isSolid() {
        return solid;
    }
    
    public Rectangle getBox() {
        return box;
    }
    
    public boolean collidesWith(Entity e) {
        if(box.intersects(e.getBox())) {
            return true;
        } else {
            return false;
        }
    }
    
    public void setBox(int wid, int hei, int xoff, int yoff) {
        box = new Rectangle(x + xoff, y + yoff, wid, hei);
    }
    
    // Called when someone attempts to draw this entity to the screen.
    public void draw(Graphics2D g) {
        g.drawImage(picture.getFrame(picture_current_frame), x, y, null);
    }
    
    public int compareTo(Entity e) {
        if(e.getDepth() > depth)
            return 1;
        else if(e.getDepth() < depth)
            return -1;
        else
            return 0;
    }
}
